home *** CD-ROM | disk | FTP | other *** search
- /* ObWind.c
- * Routines to handle cWindow objects
- * ©1992 Working Software, Inc.
- * This source code is copyrighted. Permission is granted to use the Word Services
- * portion of the Writeswell Jr. source code in your own programs, but you
- * may not distribute the Writeswell Jr. word-processor code as a
- * commercial product. If you modify the code, please do not call it
- * Writeswell Jr. (or Writeswell.) This will ensure that people understand the
- * program and don’t have to deal with a number of different versions with
- * who-knows-what going on in the code.
- *
- * Writeswell Jr. and Writeswell are trademarks of Working Software, Inc.
- * 24 Dec 91 Mike Crawford
- */
- #include <AppleEvents.h>
- #include <AEObjects.h>
- #include <AEPackObject.h>
- #include <AERegistry.h>
- #include "AppEvents.h"
- #include "ObWind.h"
- #include "ObText.h"
- #include "ObOSpec.h"
- #include "Gripe.h"
-
- OSErr WindGetDataHandler( AEDesc *tokenPtr,
- AppleEvent *theAppleEventPtr,
- AppleEvent *replyEventPtr,
- long refCon );
- OSErr WindSetDataHandler( AEDesc *tokenPtr,
- AppleEvent *theAppleEventPtr,
- AppleEvent *replyEventPtr,
- long refCon );
- OSErr WindCountHandler( AEDesc *tokenPtr,
- AppleEvent *theAppleEventPtr,
- AppleEvent *replyEventPtr,
- long refCon );
-
- /* Given the the direct object of an event is a window token (or property thereof),
- * do the requested event.
- */
- OSErr DispatchWind( AEDesc *tokenPtr,
- AppleEvent *theAppleEventPtr,
- AppleEvent *replyEventPtr,
- long refCon )
- {
- OSErr err;
- AEEventClass theClass;
- AEEventID theID;
-
- /* This function is only for the Core suit. Get the event ID from the appleEvent
- */
-
- err = GetEventID( theAppleEventPtr, &theID );
-
- switch ( theID ){
- case kAEGetData:
- err = WindGetDataHandler( tokenPtr, theAppleEventPtr, replyEventPtr, refCon );
- break;
- case kAESetData:
- err = WindSetDataHandler( tokenPtr, theAppleEventPtr, replyEventPtr, refCon );
- break;
- case kAECountElements:
- err = WindCountHandler( tokenPtr, theAppleEventPtr, replyEventPtr, refCon );
- default:
- err = errAEEventNotHandled;
- break;
- }
-
- return noErr;
- }
-
- /* The handlers for the various events */
-
- /* Get Data */
-
- OSErr WindGetDataHandler( AEDesc *tokenPtr,
- AppleEvent *theAppleEventPtr,
- AppleEvent *replyEventPtr,
- long refCon )
- {
- WindowPtr wp;
- DescType propCode;
- WindTokenBody **tokHdl;
- AEDesc replyValue;
- Str255 tmpStr;
- OSErr err;
-
- /* Sanity check */
- if ( tokenPtr->descriptorType != cWindow ){
- Gripe( "\pGot wrong token type" );
- return errAEEventNotHandled;
- }
-
- tokHdl = (WindTokenBody**)(tokenPtr->dataHandle);
-
- wp = (*tokHdl)->theWindowPtr;
- propCode = (*tokHdl)->propertyCode;
-
- if ( !wp ){
- Gripe( "\pAttempting to get data for non-existent window" );
- return errAENoSuchObject;
- }
-
- switch ( propCode ){
- case typeNull:
- /* This is a magic number for "Not A Property". I don't know if this
- * is really kosher - gotta ask, but it is a convenience.
- */
-
- /* Should return a string for object browsers */
- Gripe( "\pTrying to GetData on a window object" );
- return errAENoSuchObject;
- break;
- case pName:
- GetWTitle( wp, tmpStr );
-
- err = AECreateDesc( typeChar,
- (Ptr)&(tmpStr[1]),
- (Size)tmpStr[0],
- &replyValue );
- if ( err ){
- Gripe( "\pAECreateDesc failed" );
- return err;
- }
- break;
- case pBounds:
- case pClass:
- case pHasTitleBar:
- case pIndex:
- case pIsModal:
- case pIsResizable:
- case pIsZoomed:
- case pVisible:
- Gripe( "\pGot a property type we do not yet implement" );
- return errAENoSuchObject;
- break;
- default:
- Gripe( "\pUnknown property type" );
- return errAENoSuchObject;
- break;
- }
-
- /* At this point we have some kind of descriptor to stick in the reply */
-
- err = AEPutParamDesc( replyEventPtr,
- keyDirectObject,
- &replyValue );
- if ( err ){
- Gripe( "\pAEPutParamDesc failed" );
- return err;
- }
-
- err = AEDisposeDesc( &replyValue );
- if ( err ){
- Gripe( "\pAEDisposeDesc failed" );
- return err;
- }
-
- return noErr;
- }/* WindGetDataHandler */
-
- /* Set Data */
-
- OSErr WindSetDataHandler( AEDesc *tokenPtr,
- AppleEvent *theAppleEventPtr,
- AppleEvent *replyEventPtr,
- long refCon )
- {
- WindowPtr wp;
- DescType propCode;
- WindTokenBody **tokHdl;
- AEDesc newValue;
- AEDesc textValue;
- OSErr err;
-
- /* Sanity check */
- if ( tokenPtr->descriptorType != cWindow ){
- Gripe( "\pGot wrong token type" );
- return errAEEventNotHandled;
- }
-
- tokHdl = (WindTokenBody**)(tokenPtr->dataHandle);
-
- wp = (*tokHdl)->theWindowPtr;
- propCode = (*tokHdl)->propertyCode;
-
- if ( !wp ){
- Gripe( "\pAttempting to set data in non-existent window" );
- return errAENoSuchObject;
- }
-
- /* Get the value to set, whatever it is */
-
- err = AEGetParamDesc( theAppleEventPtr,
- keyAEData,
- typeWildCard,
- &newValue );
- if ( err ){
- Gripe( "\pAEGetParamDesc failed to get keyAEData" );
- return err;
- }
-
- switch ( propCode ){
- case typeNull:
- /* This is a magic number for "Not A Property". I don't know if this
- * is really kosher - gotta ask, but it is a convenience.
- */
-
- /* I don't think it makes sense to Set Data on a window */
- return errAEEventNotHandled;
- break;
- case pName:
-
- /* Make sure that the name is of type text */
- err = AECoerceDesc( &newValue,
- typePString,
- &textValue );
- if ( err ){
- Gripe( "\pAECoerceDesc failed to coerce to text" );
- return err;
- }
-
- HLock( textValue.dataHandle );
-
- SetWTitle( wp, (ConstStr255Param) *(textValue.dataHandle) );
-
- HUnlock( textValue.dataHandle );
-
- err = AEDisposeDesc( &textValue );
-
- if ( err ){
- Gripe( "\pAEDisposeDesc textValue failed" );
- return err;
- }
-
- break;
- case pBounds:
- case pClass:
- case pHasTitleBar:
- case pIndex:
- case pIsModal:
- case pIsResizable:
- case pIsZoomed:
- case pVisible:
- Gripe( "\pGot a property type we do not yet implement" );
- return errAENoSuchObject;
- break;
- default:
- Gripe( "\pUnknown property type" );
- return errAENoSuchObject;
- break;
- }
-
- /* At this point we are done with the newValue descriptor */
-
- err = AEDisposeDesc( &newValue );
-
- if ( err ){
- Gripe( "\pAEDisposeDesc newValue failed" );
- return err;
- }
-
- return noErr;
- }/* WindSetDataHandler */
-
- /* Count Elements */
-
- OSErr WindCountHandler( AEDesc *tokenPtr,
- AppleEvent *theAppleEventPtr,
- AppleEvent *replyEventPtr,
- long refCon )
- {
- WindowPtr wp;
- DescType propCode;
- WindTokenBody **tokHdl;
- AEDesc replyValue;
- AEDesc elementClassDesc;
- DescType elementClass;
- long count;
- OSErr err;
-
- /* Sanity check */
- if ( tokenPtr->descriptorType != cWindow ){
- Gripe( "\pGot wrong token type" );
- return errAEEventNotHandled;
- }
-
- tokHdl = (WindTokenBody**)(tokenPtr->dataHandle);
-
- wp = (*tokHdl)->theWindowPtr;
- propCode = (*tokHdl)->propertyCode;
-
- if ( !wp ){
- Gripe( "\pAttempting to count elements for non-existent window" );
- return errAENoSuchObject;
- }
-
- /* Get the class of element that we want to count. We could reasonably
- * count the letters of the title property, for example. Presently we
- * only support counting the object specifier elements for the word services
- * table checking method.
- */
-
- err = AEGetParamDesc( theAppleEventPtr,
- keyAEObjectClass,
- typeType,
- &elementClassDesc );
- if ( err ){
- Gripe( "\pCould not get object class from Count Elements event" );
- return err;
- }
-
- elementClass = *(DescType*)(*elementClassDesc.dataHandle);
-
- switch ( propCode ){
- case typeNull:
- /* This is a magic number for "Not A Property". I don't know if this
- * is really kosher - gotta ask, but it is a convenience.
- */
-
- /* In this case, we are counting the actual elements of the window. This
- * can be a text field or an object specifier. We check to see what
- * kind of element is desired, and call a function for that class to count
- * it.
- *
- * We do not yet handle the case where we could have multiple containers.
- */
-
- switch ( elementClass ){
- case cText:
- err = CountTextInWind( wp, &count );
- if ( err )
- return err;
- break;
- case typeObjectSpecifier:
- err = CountOSpecInWind( wp, &count );
- if ( err )
- return err;
- break;
- default:
- return errAENoSuchObject;
- break;
- }
-
- err = AECreateDesc( typeLongInteger, (Ptr)&count, sizeof( count ), &replyValue );
- if ( err ){
- Gripe( "\pAECreateDesc failed" );
- return err;
- }
- break;
- case pName:
- case pBounds:
- case pClass:
- case pHasTitleBar:
- case pIndex:
- case pIsModal:
- case pIsResizable:
- case pIsZoomed:
- case pVisible:
- /* In all of these cases, we are counting the elements of a property.
- * This makes more sense than it might seem. It is reasonable to count
- * the letters in the name, for example.
- */
- Gripe( "\pGot a property type we do not yet implement" );
- return errAENoSuchObject;
- break;
- default:
- Gripe( "\pUnknown property type" );
- return errAENoSuchObject;
- break;
- }
-
- /* At this point we have some kind of descriptor to stick in the reply */
-
- err = AEPutParamDesc( replyEventPtr,
- keyDirectObject,
- &replyValue );
- if ( err ){
- Gripe( "\pAEPutParamDesc failed" );
- return err;
- }
-
- err = AEDisposeDesc( &replyValue );
- if ( err ){
- Gripe( "\pAEDisposeDesc failed" );
- return err;
- }
-
- return noErr;
- }
-
- /* Return a Window token given a null (application) token */
-
- pascal OSErr WindFromNull(DescType desiredClass,
- const AEDesc *container,
- DescType containerClass,
- DescType form,
- const AEDesc *selectionData,
- AEDesc *theToken,
- long LongInt)
- {
- AEDesc longKeyData;
- WindowPtr wp;
- long count;
- WindTokenBody tokData;
- OSErr err;
-
- /* Check that the container is what we intend. This should only happen if we
- * installed the token handler incorrectly.
- */
-
- if ( container->descriptorType != typeNull )
- return errAEEventNotHandled;
-
- /* find the window based on the key form */
-
- switch ( form ){
- case formAbsolutePosition:
- /* Make sure we really have a type long descriptor */
- err = AECoerceDesc( selectionData, typeLongInteger, &longKeyData );
- if ( err ){
- Gripe( "\pAECoerceDesc failed" );
- return err;
- }
-
- count = **(long**)(longKeyData.dataHandle);
-
- /* We're done with the descriptor created in the coercion */
-
- err = AEDisposeDesc( &longKeyData );
- if ( err ){
- Gripe( "\pAEDisposeDesc failed" );
- return err;
- }
-
- /* In our particular case, we can have at most one window, but we write
- * this in a general way for reusability... scan the window list for the
- * window
- */
-
- wp = FrontWindow();
-
- while( count > 1 && wp != (WindowPtr)NULL ){
- wp = (WindowPtr)((WindowPeek)wp)->nextWindow;
- }
-
- if ( wp == (WindowPtr)NULL ){
- Gripe( "\pNo window found" );
- return errAENoSuchObject;
- }
-
- /* Actually create the token that we return */
- tokData.theWindowPtr = wp;
- tokData.propertyCode = typeNull; /* This means it's not a property */
-
- err = AECreateDesc( desiredClass, (Ptr)&tokData, sizeof( tokData ), theToken );
- if ( err ){
- Gripe( "\pAECreateDesc failed to create a token" );
- return err;
- }
-
- return noErr;
- break;
- case formRelativePosition:
- case formTest:
- case formRange:
- case formPropertyID:
- case formName:
- return errAEEventNotHandled; /* Flesh this out later */
- break;
- default:
- Gripe( "\pGot unexpected key form" );
- return errAEEventNotHandled;
- }
-
- return noErr;
- }
-
- /* Return a property token given a cWindow token. This works for any property of a window */
-
- pascal OSErr PropFromWind(DescType desiredClass,
- const AEDesc *container,
- DescType containerClass,
- DescType form,
- const AEDesc *selectionData,
- AEDesc *theToken,
- long LongInt)
- {
- OSErr err;
- DescType propType;
-
- /* Check that the container is what we intend. This should only happen if we
- * installed the token handler incorrectly.
- */
-
- if ( container->descriptorType != cWindow )
- return errAEEventNotHandled;
-
- if ( form != formPropertyID ){
- Gripe( "\pExpected formPropertyID" );
- return errAEEventNotHandled;
- }
-
- propType = **( (DescType**)(selectionData->dataHandle) );
-
- /* All we really do here is shove the property type into the token, if we
- * know about the property type
- */
-
- switch ( propType ){
- case pName:
- break;
- case pBounds:
- case pClass:
- case pHasTitleBar:
- case pIndex:
- case pIsModal:
- case pIsResizable:
- case pIsZoomed:
- case pVisible:
- Gripe( "\pGot a property type we do not yet implement" );
- return errAENoSuchObject;
- break;
- default:
- Gripe( "\pUnknown property type" );
- return errAENoSuchObject;
- break;
- }
-
- /* All we do in the token is put the propType into it. We can start with the
- * container descriptor as it has some of the fields filled in already.
- */
-
- err = AEDuplicateDesc( container, theToken );
- if ( err ){
- Gripe( "\pAEDuplicateDesc failed" );
- return err;
- }
-
- (*(WindTokenBody**)(theToken->dataHandle))->propertyCode = propType;
-
- return noErr;
- }
-
- /*
- * Descriptor packing routines
- */
-
- /* Create a formAbsolutePosition window descriptor */
-
- OSErr BuildWindowSpecifier( AEDesc *specPtr, long whichWindow )
- {
- AEDesc nullDesc;
- AEDesc nullSpec;
- AEDesc whichDesc;
- OSErr err;
-
- /* Create the descriptor for the container (the application, or null) */
-
- err = AECreateDesc( typeNull, (Ptr)NULL, (Size)0, &nullDesc );
- if ( err )
- return err;
-
- /* Create the key data, which gives the window number */
-
- err = CreateOffsetDescriptor( whichWindow, &whichDesc );
- if ( err )
- return err;
-
- /* Create the Object Specifier for the window */
-
- err = CreateObjSpecifier( cWindow,
- &nullDesc,
- formAbsolutePosition,
- &whichDesc,
- true, /* Dispose of input descriptors */
- specPtr ); /* specPtr is the value we return */
- return err;
- }